home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / m68k / cc68k.arc / GETSYM.C < prev    next >
C/C++ Source or Header  |  1986-10-26  |  18KB  |  557 lines

  1. #include        "stdio.h"
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7. /*
  8.  *    68000 C compiler
  9.  *
  10.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  11.  *  all commercial rights reserved.
  12.  *
  13.  *    This compiler is intended as an instructive tool for personal use. Any
  14.  *    use for profit without the written consent of the author is prohibited.
  15.  *
  16.  *    This compiler may be distributed freely for non-commercial use as long
  17.  *    as this notice stays intact. Please forward any enhancements or question
  18. s
  19.  *    to:
  20.  *
  21.  *        Matthew Brandt
  22.  *        Box 920337
  23.  *        Norcross, Ga 30092
  24.  */
  25.  
  26. static int      errno[80];
  27. static int      numerrs;
  28. static char     inline[132];
  29. int             total_errors = 0;
  30. extern char            *lptr;          /* shared with preproc */
  31. extern FILE            *inclfile[10];  /* shared with preproc */
  32. extern int             inclline[10];   /* shared with preproc */
  33. extern int             incldepth;      /* shared with preproc */
  34. char            *linstack[20];  /* stack for substitutions */
  35. char            chstack[20];    /* place to save lastch */
  36. int             lstackptr = 0;  /* substitution stack pointer */
  37.  
  38. int     isalnum(c)
  39. char    c;
  40. {       return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
  41.                 (c >= '0' && c <= '9');
  42. }
  43.  
  44.  
  45. int     isidch(c)
  46. char    c;
  47. {       return isalnum(c) || c == '_' || c == '$';
  48. }
  49.  
  50. int     isspace(c)
  51. char    c;
  52. {       return c == ' ' || c == '\t' || c == '\n';
  53. }
  54.  
  55.  
  56. int     isdigit(c)
  57. char    c;
  58. {       return (c >= '0' && c <= '9');
  59. }
  60.  
  61.  initsym()
  62. {       lptr = inline;
  63.         inline[0] = 0;
  64.         numerrs = 0;
  65.         total_errors = 0;
  66.         lineno = 0;
  67. }
  68.  
  69. int     getline(listflag)
  70. int     listflag;
  71. {       int     rv;
  72.         if( lineno > 0 && listflag) {
  73.                 fprintf(list,"%6d\t%s",lineno,inline);
  74.                 while(numerrs--)
  75.                         fprintf(list," *** error %d\n",errno[numerrs]);
  76.                 numerrs = 0;
  77.                 }
  78.         ++lineno;
  79.         rv = (fgets(inline,131,input) == NULL);
  80.         if( rv && incldepth > 0 ) {
  81.                 fclose(input);
  82.                 input = inclfile[--incldepth];
  83.                 lineno = inclline[incldepth];
  84.                 return getline(0);
  85.                 }
  86.         if( rv )
  87.                 return 1;
  88.         lptr = inline;
  89.         if(inline[0] == '#')
  90.               /*  return */  preprocess();
  91.         return 0;
  92. }
  93.  
  94. /*
  95.  *      getch - basic get character routine.
  96.  */
  97. int     getch()
  98. {       while( (lastch =(int) *lptr++) == '\0') {
  99.                 if( lstackptr > 0 ) {
  100.                         lptr = linstack[--lstackptr];
  101.                         lastch =(int) chstack[lstackptr];
  102.                         return lastch;
  103.                         }
  104.                 if(getline(incldepth == 0))
  105.                         return lastch = -1;
  106.                 }
  107.         return lastch;
  108. }
  109.  
  110. /*
  111.  *      error - print error information
  112.  */
  113.  error(n)
  114. int     n;
  115. {       errno[numerrs++] = n;
  116.         ++total_errors;
  117. }
  118.  
  119. /*
  120.  *      getid - get an identifier.
  121.  *
  122.  *      identifiers are any isidch conglomerate
  123.  *      that doesn't start with a numeric character.
  124.  *      this set INCLUDES keywords.
  125.  */
  126.      getid()
  127. {       register int    i;
  128.         i = 0;
  129.         while(isidch(lastch)) {
  130.                 if(i < 19)
  131.                         lastid[i++] = lastch;
  132.                 getch();
  133.                 }
  134.         lastid[i] = '\0';
  135.         lastst = id;
  136. }
  137.  
  138. /*
  139.  *      getsch - get a character in a quoted string.
  140.  *
  141.  *      this routine handles all of the escape mechanisms
  142.  *      for characters in strings and character constants.
  143.  */
  144. int     getsch()        /* return an in-quote character */
  145. {       register int    i, j;
  146.         if(lastch == '\n')
  147.                 return -1;
  148.         if(lastch != '\\') {
  149.                 i = lastch;
  150.                 getch();
  151.                 return i;
  152.                 }
  153.         getch();        /* get an escaped character */
  154.         if(isdigit(lastch)) {
  155.                 i = 0;
  156.                 for(j = 0;j < 3;++j) {
  157.                         if(lastch <= '7' && lastch >= '0')
  158.                                 i = (i << 3) + lastch - '0';
  159.                         else
  160.                                 break;
  161.                         getch();
  162.                         }
  163.                 return i;
  164.                 }
  165.         i = lastch;
  166.         getch();
  167.         switch(i) {
  168.                 case '\n':
  169.                         getch();
  170.                         return getsch();
  171.                 case 'b':
  172.                         return '\b';
  173.                 case 'f':
  174.                         return '\f';
  175.                 case 'n':
  176.                         return '\n';
  177.                 case 'r':
  178.                         return '\r';
  179.                 case 't':
  180.                         return '\t';
  181.                 default:
  182.                         return i;
  183.                 }
  184. }
  185.  
  186. int     radix36(c)
  187. char    c;
  188. {       if(isdigit(c))
  189.                 return c - '0';
  190.         if(c >= 'a' && c <= 'z')
  191.                 return c - 'a' + 10;
  192.         if(c >= 'A' && c <= 'Z')
  193.                 return c - 'A' + 10;
  194.         return -1;
  195. }
  196.  
  197. /*
  198.  *      getbase - get an integer in any base.
  199.  */
  200.  getbase(b)
  201. int b;
  202. {       register int    i, j;
  203.         i = 0;
  204.         while(isalnum(lastch)) {
  205.                 if((j = radix36(lastch)) < b) {
  206.                         i = i * b + j;
  207.                         getch();
  208.                         }
  209.                 else break;
  210.                 }
  211.         ival =(long) i;
  212.         lastst = iconst;
  213. }
  214.  
  215. /*
  216.  *      getfrac - get fraction part of a floating number.
  217.  */
  218.  getfrac()
  219. {       double  frmul;
  220.         frmul = 0.1;
  221.         while(isdigit(lastch)) {
  222.                 rval += frmul * (lastch - '0');
  223.                 getch();
  224.                 frmul *= 0.1;
  225.                 }
  226. }
  227.  
  228. /*
  229.  *      getexp - get exponent part of floating number.
  230.  *
  231.  *      this algorithm is primative but usefull.  Floating
  232.  *      exponents are limited to +/-255 but most hardware
  233.  *      won't support more anyway.
  234.  */
  235.  getexp()
  236. {       double  expo, exmul;
  237.         expo = 1.0;
  238.         if(lastst != rconst)
  239.                 rval =(0.0)+ ival;
  240.         if(lastch = '-') {
  241.                 exmul = 0.1;
  242.                 getch();
  243.                 }
  244.         else
  245.                 exmul = 10.0;
  246.         getbase(10);
  247.         if(ival > 255)
  248.                 error(ERR_FPCON);
  249.         else
  250.                 while(ival--)
  251.                         expo *= exmul;
  252.         rval *= expo;
  253. }
  254.  
  255. /*
  256.  *      getnum - get a number from input.
  257.  *
  258.  *      getnum handles all of the numeric input. it accepts
  259.  *      decimal, octal, hexidecimal, and floating point numbers.
  260.  */
  261.  getnum()
  262. {       register int    i;
  263.         i = 0;
  264.         if(lastch == '0') {
  265.                 getch();
  266.                 if(lastch == 'x' || lastch == 'X') {
  267.                         getch();
  268.                         getbase(16);
  269.                         }
  270.                 else getbase(8);
  271.                 }
  272.         else    {
  273.                 getbase(10);
  274.                 if(lastch == '.') {
  275.                         getch();
  276.                         rval =(0.0)+ ival;    /* float the integer part */
  277.                         getfrac();      /* add the fractional part */
  278.                         lastst = rconst;
  279.                         }
  280.                 if(lastch == 'e' || lastch == 'E') {
  281.                         getch();
  282.                         getexp();       /* get the exponent */
  283.                         }
  284.                 }
  285. }
  286.  
  287. /*
  288.  *      getsym - get next symbol from input stream.
  289.  *
  290.  *      getsym is the basic lexical analyzer.  It builds
  291.  *      basic tokens out of the characters on the input
  292.  *      stream and sets the following global variables:
  293.  *
  294.  *      lastch:         A look behind buffer.
  295.  *      lastst:         type of last symbol read.
  296.  *      laststr:        last string constant read.
  297.  *      lastid:         last identifier read.
  298.  *      ival:           last integer constant read.
  299.  *      rval:           last real constant read.
  300.  *
  301.  *      getsym should be called for all your input needs...
  302.  */     getsym()
  303. {       register int    i, j;
  304.         SYM             *sp;
  305. restart:        /* we come back here after comments */
  306.         while(isspace(lastch))
  307.                 getch();
  308.         if( lastch == -1)
  309.                 lastst = eof;
  310.         else if(isdigit(lastch))
  311.                 getnum();
  312.         else if(isidch(lastch)) {
  313.                 getid();
  314.                 if( (sp =(SYM *) search(lastid,defsyms.head)) != 0 ) {
  315.                         linstack[lstackptr] = lptr;
  316.                         chstack[lstackptr++] = lastch;
  317.                         lptr = sp->value.s;
  318.                         getch();
  319.                         goto restart;
  320.                         }
  321.                 }
  322.         else switch(lastch) {
  323.                 case '+':
  324.                         getch();
  325.                         if(lastch == '+') {
  326.                                 getch();
  327.                                 lastst = autoinc;
  328.                                 }
  329.                         else if(lastch == '=') {
  330.                                 getch();
  331.                                 lastst = asplus;
  332.                                 }
  333.                         else lastst = plus;
  334.                         break;
  335.                 case '-':
  336.                         getch();
  337.                         if(lastch == '-') {
  338.                                 getch();
  339.                                 lastst = autodec;
  340.                                 }
  341.                         else if(lastch == '=') {
  342.                                 getch();
  343.                                 lastst = asminus;
  344.                                 }
  345.                         else if(lastch == '>') {
  346.                                 getch();
  347.                                 lastst = pointsto;
  348.                                 }
  349.                         else lastst = minus;
  350.                         break;
  351.                 case '*':
  352.                         getch();
  353.                         if(lastch == '=') {
  354.                                 getch();
  355.                                 lastst = astimes;
  356.                                 }
  357.                         else lastst = star;
  358.                         break;
  359.                 case '/':
  360.                         getch();
  361.                         if(lastch == '=') {
  362.                                 getch();
  363.                                 lastst = asdivide;
  364.                                 }
  365.                         else if(lastch == '*') {
  366.                                 getch();
  367.                                 for(;;) {
  368.                                         if(lastch == '*') {
  369.                                                 getch();
  370.                                                 if(lastch == '/') {
  371.                                                         getch();
  372.                                                         goto restart;
  373.                                                         }
  374.                                                 }
  375.                                         else
  376.                                                 getch();
  377.                                         }
  378.                                 }
  379.                         else lastst = divide;
  380.                         break;
  381.                 case '^':
  382.                         getch();
  383.                         lastst = uparrow;
  384.                         break;
  385.                 case ';':
  386.                         getch();
  387.                         lastst = semicolon;
  388.                         break;
  389.                 case ':':
  390.                         getch();
  391.                         lastst = colon;
  392.                         break;
  393.                 case '=':
  394.                         getch();
  395.                         if(lastch == '=') {
  396.                                 getch();
  397.                                 lastst = eq;
  398.                                 }
  399.                         else lastst = assign;
  400.                         break;
  401.                 case '>':
  402.                         getch();
  403.                         if(lastch == '=') {
  404.                                 getch();
  405.                                 lastst = geq;
  406.                                 }
  407.                         else if(lastch == '>') {
  408.                                 getch();
  409.                                 if(lastch == '=') {
  410.                                         getch();
  411.                                         lastst = asrshift;
  412.                                         }
  413.                                 else lastst = rshift;
  414.                                 }
  415.                         else lastst = gt;
  416.                         break;
  417.                 case '<':
  418.                         getch();
  419.                         if(lastch == '=') {
  420.                                 getch();
  421.                                 lastst = leq;
  422.                                 }
  423.                         else if(lastch == '<') {
  424.                                 getch();
  425.                                 if(lastch == '=') {
  426.                                         getch();
  427.                                         lastst = aslshift;
  428.                                         }
  429.                                 else lastst = lshift;
  430.                                 }
  431.                         else lastst = lt;
  432.                         break;
  433.                 case '\'':
  434.                         getch();
  435.                         ival =(long) getsch();        /* get a string char */
  436.                         if(lastch != '\'')
  437.                                 error(ERR_SYNTAX);
  438.                         else
  439.                                 getch();
  440.                         lastst = iconst;
  441.                         break;
  442.                 case '\"':
  443.                         getch();
  444.                         for(i = 0;i < MAX_STRLEN;++i) {
  445.                                 if(lastch == '\"')
  446.                                         break;
  447.                                 if((j = getsch()) == -1)
  448.                                         break;
  449.                                 else
  450.                                         laststr[i] = j;
  451.                                 }
  452.                         laststr[i] = 0;
  453.                         lastst = sconst;
  454.                         if(lastch != '\"')
  455.                                 error(ERR_SYNTAX);
  456.                         else
  457.                                 getch();
  458.                         break;
  459.                 case '!':
  460.                         getch();
  461.                         if(lastch == '=') {
  462.                                 getch();
  463.                                 lastst = neq;
  464.                                 }
  465.                         else lastst = not;
  466.                         break;
  467.                 case '%':
  468.                         getch();
  469.                         if(lastch == '=') {
  470.                                 getch();
  471.                                 lastst = asmodop;
  472.                                 }
  473.                         else lastst = modop;
  474.                         break;
  475.                 case '~':
  476.                         getch();
  477.                         lastst = compl;
  478.                         break;
  479.                 case '.':
  480.                         getch();
  481.                         lastst = dot;
  482.                         break;
  483.                 case ',':
  484.                         getch();
  485.                         lastst = comma;
  486.                         break;
  487.                 case '&':
  488.                         getch();
  489.                         if( lastch == '&') {
  490.                                 lastst = land;
  491.                                 getch();
  492.                                 }
  493.                         else if( lastch == '=') {
  494.                                 lastst = asand;
  495.                                 getch();
  496.                                 }
  497.                         else
  498.                                 lastst = and;
  499.                         break;
  500.                 case '|':
  501.                         getch();
  502.                         if(lastch == '|') {
  503.                                 lastst = lor;
  504.                                 getch();
  505.                                 }
  506.                         else if( lastch == '=') {
  507.                                 lastst = asor;
  508.                                 getch();
  509.                                 }
  510.                         else
  511.                                 lastst = or;
  512.                         break;
  513.                 case '(':
  514.                         getch();
  515.                         lastst = openpa;
  516.                         break;
  517.                 case ')':
  518.                         getch();
  519.                         lastst = closepa;
  520.                         break;
  521.                 case '[':
  522.                         getch();
  523.                         lastst = openbr;
  524.                         break;
  525.                 case ']':
  526.                         getch();
  527.                         lastst = closebr;
  528.                         break;
  529.                 case '{':
  530.                         getch();
  531.                         lastst = begin;
  532.                         break;
  533.                 case '}':
  534.                         getch();
  535.                         lastst = end;
  536.                         break;
  537.                 case '?':
  538.                         getch();
  539.                         lastst = hook;
  540.                         break;
  541.                 default:
  542.                         getch();
  543.                         error(ERR_ILLCHAR);
  544.                         goto restart;   /* get a real token */
  545.                 }
  546.         if(lastst == id)
  547.                 searchkw();
  548. }
  549.  
  550.  needpunc(p)
  551. enum e_sym      p;
  552. {       if( lastst == p)
  553.                 getsym();
  554.         else
  555.                 error(ERR_PUNCT);
  556. }
  557.